package com.crime.crimemonitorclient;

import android.app.Activity;
import android.app.Fragment;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.os.AsyncTask.Status;
import android.os.Bundle;
import android.widget.Toast;

public abstract class RetainedAsyncTaskFragment<Result, ResultHandler> extends Fragment implements AsyncTaskHandler<Result>
{
	protected RetainedAsyncTask<Result> mTask;	
	protected ResultHandler mResultHandler;
	protected ProgressDialog mProgressDialog;
	private InfiniteActivityIndicatorProvider mActivityIndicatorProvider;

	
	@Override
	public void onPreExecute()
	{
		this.showProgressDialog();
	}

	@Override
	public void onPostExecute(Result result)
	{
		this.dismissProgressDialog();
		this.callResultHandler(result);
	}

	protected abstract void callResultHandler(Result result);

	@Override
	public void onCancelled(Result result)
	{
		this.dismissProgressDialog();
		
		Toast.makeText(
				this.getActivity(),
				this.getActivity().getResources().getString(
						this.getCancelledMessageResourceStringId()),
				Toast.LENGTH_LONG).show();
	}

	//protected ProgressDialog mProgressDialog;
	
	
	protected abstract int getCancelledMessageResourceStringId();

	@Override
	public void onAttach(Activity activity)
	{
		super.onAttach(activity);
		
		try
		{
			mResultHandler = (ResultHandler)activity;
			//mProgressDialog = new ProgressDialog(this.getActivity());
		}
		catch(ClassCastException e)
		{
			throw new ClassCastException(String.format("Activity must implement ResultHandler")); 
		}
		
		try
		{
			mActivityIndicatorProvider = (InfiniteActivityIndicatorProvider)activity;
			//mProgressDialog = new ProgressDialog(this.getActivity());
		}
		catch(ClassCastException e)
		{
			throw new ClassCastException(String.format("Activity must implement InfiniteActivityIndicatorProvider")); 
		}
			
		if(mTask != null)
			if(mTask.getStatus() != Status.FINISHED)
			{
				mTask.onAttach(this);
				this.showProgressDialog();
			}
			else
				mTask = null;
		
	}
	
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		// tento fragment se bude uchovavat mezi instancemi
		// Nemelo by se nastavovat z aktivity?
		this.setRetainInstance(true);
	}
	
	@Override
	public void onDetach()
	{
		super.onDetach();
		
		// set references to callback handler to null to prevent memory leaks
		mResultHandler = null;
		this.dismissProgressDialog();
		mProgressDialog = null;
		
		if(mTask != null)
		{
			mTask.onDetach();
			
			if(mTask.getStatus() == Status.FINISHED)
				mTask = null;
		}
	}

	public void runTask() throws IllegalStateException, NullPointerException, IllegalArgumentException
	{
		// TODO: mTask != null && mTask.getStatus() == Status.FINISHED, jinak exception?
		if(this.isTaskRunningOrPending())
			throw new IllegalStateException("Task pending or still running.");
		
		if(mTask != null)
			mTask.onDetach();
		
		mTask = this.createTask();

		mTask.execute();
	}

	public boolean isTaskRunningOrPending()
	{
		return
				mTask != null && (mTask.getStatus() == Status.PENDING || mTask.getStatus() == Status.RUNNING);  
	}
	
	
	protected abstract RetainedAsyncTask<Result> createTask();
	

	private void showProgressDialog()
	{
//		mProgressDialog.setTitle(this.getProgressDialogTitle());
//		mProgressDialog.setIndeterminate(true);
//		mProgressDialog.setCanceledOnTouchOutside(false);
//		mProgressDialog.setCancelable(true);
//		mProgressDialog.setOnCancelListener(new OnCancelListener()
//		{
//			@Override
//			public void onCancel(DialogInterface dialog)
//			{
//				mTask.cancel(false);
//			}
//		});
//
//		mProgressDialog.show();
		mActivityIndicatorProvider.show();
	}
	
	protected abstract CharSequence getProgressDialogTitle();

	private void dismissProgressDialog()
	{
//		if(mProgressDialog.isShowing())
//			mProgressDialog.dismiss();
		mActivityIndicatorProvider.dismiss();
	}
	
}
